package com.lx.boot.web.convert.serializer;

import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.lx.annotation.Note;
import com.lx.boot.web.convert.DFunction;
import com.lx.util.LX;
import com.lx.util.secure.algorithm.coder.CoderType;

import java.lang.annotation.*;

@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.TYPE,ElementType.PARAMETER})
@Documented
@JacksonAnnotationsInside
@Serializer(value = SensitiveSerializer.class,function = SensitiveSerializer.EecoderDFunction.class)
@Note("返回值脱敏处理器")
public @interface SensitiveSerializer {

    @Note("从第几位开始替换")
    int start() default 0;

    @Note("从第几位结束替换")
    int end() default 0;

    @Note("替换后的字符")
    char reChar() default '*';

    @Note("脱敏规则, 为 CUSTOM 取自定义参数")
    SensitiveType sensitiveType() default SensitiveType.CUSTOM;

    public static class EecoderDFunction implements DFunction<SerializerPara, SensitiveSerializer, String> {
        @Override
        public String apply(SerializerPara para, SensitiveSerializer convert) {
            if (SensitiveType.CUSTOM == convert.sensitiveType()){
                return replaceNo((String)para.getValue(),convert.start(),convert.end(),convert.reChar());
            }else{
                return replaceNo((String)para.getValue(),convert.sensitiveType().getStart(),convert.sensitiveType().getEnd(), convert.sensitiveType().getReChar());
            }
        }
        // 替换部分字符串
        public static String replaceNo(String str, int start, int end, char charStr) {
            if (LX.isNotEmpty(str)){
                end = str.length()>end?end:str.length()-1;
                char[] charArray = str.toCharArray();
                for (int i = start; i <=end; i++) {
                    charArray[i] = charStr;
                }
                return new String(charArray);
            }
            return str;
        }
    }

    public enum SensitiveType{
        CUSTOM(0,0),
        //身份证号
        ID_CARD(3,14),
        //手机号
        PHONE(3,7),
        //地址
        ADDRESS(3,50),
        //邮箱
        EMAIL(0,5),
        //银行卡
        BANK_CARD(3,10);
        int start;
        int end;
        char reChar = '*';

        SensitiveType(int start, int end) {
            this.start = start;
            this.end = end;
            this.reChar = '*';
        }
        SensitiveType(int start, int end, char reChar) {
            this.start = start;
            this.end = end;
            this.reChar = reChar;
        }

        public int getStart() {
            return start;
        }

        public int getEnd() {
            return end;
        }

        public char getReChar() {
            return reChar;
        }
    }

}
